//详情页
/**
 * 使用window自带方法location的一个属性search就获取到了从?开始我们后边跟的那个id,但是因为是 ?id=0 这种格式的,所以需要用字符串截的方法slice()将后边的需要用到的id值截取到
*/
require(['./config'], () => {
    require(['header', 'template', 'footer','zoom'], (Header,template) => {
        class Details {
            constructor() {
                this.header()
                this.init().then(() => {//其他方法都是在页面熏染完毕后才会出现的,所以需要依赖于页面渲染方法
                    this.zoom()//放大镜功能(插件)
                    this.soping()//购物选择区功能
                    this.addCart()//点击按钮功能(实现点击时记录所有商品详情数据并上传到localStrong中且实现点击的时候时实时更新商品显示区中的内容)
                    this.ShoppingCart()//商品显示区功能
                })
            }
            header() {
                new Header()
            }
            init() {
                console.log(window.location.search);//获取到的字符串为形如 ?id=0 这种格式的,需要用字符串截的方法将值截取出来
                const id = parseInt(window.location.search.slice(4));//用paseint转为整数
                console.log(id);//这样就把id的值取出来了
                //这个时候我们就可以根据这个id从后端接口获取到这个id商品的详细信息,然后就可以将其渲染到页面中了
                // 要把异步代码改造成同步的形式，用到Promise
                // 套路： return new Promise()
                return new Promise((resolve, reject) => {
                    // 根据id请求后端接口拿到当前商品的详情数据,但是我们这里使用的是rap2假数据接口他的数据是随机的,所以我们从前一个页面中拿到id页无法完全一摸一样的匹配到真正数据,所以我们要单独处理一下这个id假设为是由id匹配到的数据,即把id手动添加进去
                    $.get('http://rap2api.taobao.org/app/mock/244799/details', { id }, resp => {
                        // console.log(resp)
                        if (resp.code === 200) {
                            const { details } = resp.body
                            // 由于rap2接口没有返回id，所以需要手动设置一下，将来换成真实接口的时候就不需要了
                            // 把detail展开，把id写进去，最后构成一个新的对象赋值给this.detail
                            this.details = { ...details, id }
                            // console.log(this.details);
                            // 渲染详情页
                            // 把detail展开，所有属性全部传递进去
                            $('#Template').html(template('Template_01', { ...this.details }))
                            // 代表异步成功，承诺兑现
                            resolve()
                        }
                    })
                })

            }
            //放大镜插件
            zoom() {
                $('.zoom-image').elevateZoom({
                    // 指定小图容器盒子的id，不加#
                    gallery: 'minimg',
                    // 大图进行操作

                })
            }
            //购物选择区中的功能
            soping() {
                /*
                //js原生
                let ocolor_01 = document.querySelectorAll('#color span')
                console.log(ocolor_01);
                */
                //JQ方法
                // console.log(ocolor);//这个输出得是个数组
                // console.log(ocolor.html());//用上html()方法后输出其中第一个元素得html值,所以得用循环来解决这个问题
                //使用each()循环给每个span都天啊及点击事件
                
                let ocolor = $('#color span');//获取所有颜色按钮
                let oSize = $('#Size span');//获取所有尺寸按钮
                let oNum = $('#Num select');//下拉菜单直接获取一个select就行,他要做的是改变事件,不用再循环添加是事件了


                //颜色按钮功能
                ocolor.each(function(){
                    $(this).on('click',() =>{
                        //each循环中用$(this)代表此时的那个元素
                        //首先实现你点击某一个span自己改变白景色,字体颜色,然后其他兄弟元素背景色不变
                        $(this).css({ 'background': '#b81c22', 'color': 'white' });
                        //JQuery.siblings(),元素除自己以外的其他所有兄弟元素
                        $(this).siblings().css({'background':'#ffffff','color':'black'});
                        
                        //然后获取点击的这个span标签的值
                        let a = $(this).html()
                        console.log(a);//点击哪个span就输出哪个span中得值

                        //然后将这个值填写到已选区域的显示框中
                        $('#SelectedColor').html(a);

                        //定义一个数组,然后随机选择其中的元素,每选择一次随机出现一个
                        let arr=['现在有货','货物售罄']
                        let index = Math.round(Math.random());
                        console.log(arr[index]);
                        $('#HaveNo').html(arr[index]);
                    })
                })

                //尺寸按钮功能
                oSize.each(function(){
                    $(this).on('click', () => {
                        //点击时将自己背景色变为红色,其他不变
                        $(this).css({ 'background': '#b81c22', 'color':'white'})
                        //JQuery.siblings(),元素除自己以外的其他所有兄弟元素
                        $(this).siblings().css({ 'background': '#ffffff', 'color': 'black' });

                        //获取所点击的span标签中的内容
                        console.log($(this).html());
                        let b = $(this).html();

                        //然后将获取到的元素内容,填写在已选区域
                        $('#SelectedSize').html(b);

                        //再定义一个数组,然后随机选择其中的元素,每选择一次再次随机出现一个
                        //模拟真实选择时例如白色有货,但是这个型号没有
                        let arr=['现在有货','货物售罄']
                        let index = Math.round(Math.random());
                        console.log(arr[index]);
                        $('#HaveNo').html(arr[index]);

                    })
                })

                //数量选择(下拉菜单)框功能
                /**
                 * 他直接用一个改变事件就ok了,当他其中的内容发生改变时,获取他的value值就ok了
                */
                oNum.change(function(){
                    //直接获取select中的value值
                    let c = parseInt($(this).val());
                    
                    console.log($(this).val())

                    //然后将其放到已选显示区
                    if(c !== 0){//只有当val不是0的时候再填
                        $('#SelectedNum').html(c);
                        //再定义一个数组,然后随机选择其中的元素,每选择一次再次随机出现一个
                        let arr = ['现在有货', '货物售罄']
                        let index = Math.round(Math.random());
                        console.log(arr[index]);
                        $('#HaveNo').html(arr[index]);
                    }
                })
            }

            //加入购物车功能
            /**
             * 首先获取这个按钮
             * 然后点击这个按钮的时候获取详情数据,用localStorage存储这个数据(注意:localString中只能存放字符串格式的数据,所以我们要把数据编译为字符串类型,推荐使用严格json格式字符串)
             * 详情数据由我们选择商品后在页面中获取到商品名,颜色,大小,价格还有数量后,编译为JSON格式字符串保存到localStorage中
             */
            addCart() {
                $('#addCart').on('click',() =>{//使用箭头函数,当前this指向外层,可以非常方便的获取到外层的数据
                    //获取所选货物的详情详细
                    let CommodityId = parseInt(window.location.search.slice(4));//商品id从地址栏中获取
                    // console.log(CommodityId)
                    let TradeName = $('#Route p #TradeName').html();//商品名称
                    // console.log(TradeName)
                    let CommodityColor = $('#SelectedColor').html();//商品颜色
                    // console.log(CommodityColor)
                    let CommoditySize = $('#SelectedSize').html();//商品尺寸
                    // console.log(CommoditySize)
                    let CommodityNum = parseInt($('#SelectedNum').html());//商品数量
                    // console.log(CommodityNum)
                    let CommodityPirce = $('#pirce').html();//商品价格
                    // console.log(CommodityPirce);


                    /* 往localStorage中存放数据的实现思想:*/
                    /**
                     * 首先先将获取到的商品详细信息编译为json对象,然后判断一下localStrong中是否已存在数据(即购物车是否为空)
                     * 若不存在则将已经编译好的json对象格式的新数据以数组的形式(即将这个新数据放到数组中)转为json字符串并上传(存储)到localStorage中
                     * 若localStorage中已存在数据,则将其中的数据取出来,因为是字符串所以要先将其转为原格式即转回为数组才可进行下一步的操作,然后就可以将已经编译好localStorage新数据用数组push()的方法将其添加在这个数组中(这样原先的数据就不会被覆盖掉了,数组中允许出现重复元素),最后再将其转为json字符串并重新添加在localStorage中就OK了
                     */

                    /**
                     * 那么如何判断购物车中是否已存在相同的数据呢,这里我们可以使用js数组的some方法来判断转回为数组的localStorage数据中是否存在这条数据(判断的条件为:可以对商品造成重大影响的属性值是否相等,eg:id color 还有 Size 都可对商品造成重大影响)
                     * 可使用条件
                     * 原数据.id === 新数据.id  原数据.color === 新数据.color 原数据.Size === 新数据.Size
                     * 若是判断条件为true,则购物车中存在相同数据,但是num不相等,所以需要把原数据的num取出来然后合并到新数据的num上并将原数据删除,然后再将新数据用数组push的方法添加到数组中,然后保存到localStorang中即可
                     * 若是条件为 false (即只要是其中有一个条件不满足就直接false),则将新数据直添加在数组中并保存到localStroang中即可
                     * 
                     * some方法:
                     */

                    //1.将商品详细数据编译为json对象
                    let obj = {
                        "id":  CommodityId,
                        "name": TradeName, 
                        "color":  CommodityColor, 
                        "Size":  CommoditySize, 
                        "num":  CommodityNum,
                        "price":  CommodityPirce 
                    }

                    //2.判断localStrong中是否存在数据(即购物车是否为空)
                    let cart = window.localStorage.getItem('cart')//接收localStroang中扒拉下来的数据,不存在直接为null直接执行if跳到else中
                    if(cart){
                        console.log('购物车不为空执行判断购物车中是否有重复元素的操作');
                        //console.log('保存在localcalStorang中的字符串格式的数据',cart);//输出为json字符串样式的数组
                        /**
                         * localStorang中存在数据,即购物车不为空
                         * 则就可以将localStorang中的数据取出来,然后转回为数组并将新数据push在这个数组中,最后再转为json字符串并保存在localStorang
                         */
                        let arr = JSON.parse(cart);//转回为数组
                        console.log('将localStorang中的数据重新转回为数组', arr);//输出为数组
                        /**
                         * 判断购物车中是否存在相同数据
                         * 用some方法,判断一个数组中是否存在某条件类型的数据,若存在则返回true,若都不符合则才会返回false
                        */
                        let condition = arr.some(function(item,index,array){//回调函数有三个参数:1.数组中的元素,2.下标,3.数组本身
                            return item.id === obj.id && item.color === obj.color && item.Size === obj.Size;//返回一个经过条件判断之后的一个结果,布尔值
                        });
                        console.log('判断是否有重复返的回的条件',condition);
                        //如果符合条件则执行原数据与新数据的合并以及删除原数据并将新数据增添到localStroage中的操作
                        if(condition){
                            console.log('开始执行重复元素合并功能')
                            /**
                             * 若三个条件都符合了则就可以把两条数据合并起来(num相加,赋值给新新数据,删除原数据)
                             * 使用JQ的each方法循环遍历数组,找到符合条件的那个原数据元素取出其num属性值加到新数据的num上,然后删除原数据并将新数据增添上去
                             * 使用数组改的方法:splice(下标的开始位置,删除的数组长度,新增的元素,新增元素,……)
                             */
                            console.log('开始循环遍历数组')
                            $.each(arr,function(index,value){//JQ each()循环遍历数组的方法,参数1:数组;参数2:函数(参数1:下标;参数2:元素)
                                // console.log(index,value)
                                if(obj.id === value.id){
                                    // console.log('id相等');
                                    if(obj.color === value.color){
                                        // console.log('color相等');
                                        if(obj.Size === value.Size){
                                            // console.log('size相等');
                                            let num = value.num;//获取重复元素的num属性值
                                            // console.log('未合并之前的原数据num值',value.num);
                                            // console.log('未合并之前的新数据num值',obj.num);
                                            obj.num = parseInt(obj.num) + parseInt(num);
                                            // console.log('合并了之后的新数据num值',obj.num);
                                            // console.log('处理后的重复元素后的新元素',obj);
                                            arr.splice(index, 1);//删除原数据
                                            arr.push(obj);//新数据增填到数组中
                                            // console.log(arr.length);
                                            window.localStorage.setItem('cart', JSON.stringify(arr));//新数组重新保存localStorang中
                                        }
                                    }
                                }
                            })

                        } else {
                            console.log('开始执行新元素直接上传功能')
                            /**
                             * 如果不符合条件(即id color size中有任一项不符合要求),则就直接执行再填一条的功能,将新数据直接保存在localStorage中即可
                             */
                            arr.push(obj);//新数据直接增填到数组中
                            window.localStorage.setItem('cart', JSON.stringify(arr));//将跟新过后新数组重新保存localStorang中,因为名字是一样的所以会把前一次的覆盖掉,只留下更新了之后的数据,所以选择数组的方法来结合json来上传数据
                        }
                    }else{
                        console.log('购物车为空开始执行新元素直接上传功能')
                        /**
                         * localStorage中不存在数据,即购物车为空
                         * 将新数据保存在数组中直接在这里创建并赋值就信,然后JSON.stringify()转为json字符串保存在localStorang中
                         */
                        let arr = [obj];
                        window.localStorage.setItem('cart',JSON.stringify(arr))//使用localStrong的setItem来往localStrong中存放数据(两个参数:name,value)
                    }

                    //调用ShoppingCart()方法实现点击按钮的时候往商品显示区内添加信息
                    this.ShoppingCart();
                    

                })
            }

            //商品显示区功能
            /**
             * 加载完页面后读取localStorage中的数据并填写到商品显示区中的#DisplayInformation标签中
             * 当点击加入购物车按钮的时候重新加载(即调用这个显示方法然后删除掉#DisplayInformation标签然后再重新创建这个div并将数据显示到这个里边)
             */
            ShoppingCart(){
                //1.先删除一遍#DisplayInformation标签中#DisplayUl标签然后再重新创建
                $('.DisplayUl').remove();
                //取出localStorage中的数据并转回为数组形式
                let arr = JSON.parse(window.localStorage.getItem('cart'));
                $.each(arr, function (index, value) {//each循环遍历数组,将数据一一对应添加到#DisplayInformation中并显示到页面中
                    /**
                     * .append() JQ方法 在每个匹配元素里面的末尾处插入参数内容。
                     */
                    $('#DisplayInformation').append(`
                        <ul class="DisplayUl">
                            <li>${value.name}</li>
                            <li>${value.price}</li>
                            <li>${value.color}</li>
                            <li>${value.Size}</li>
                            <li>${value.num}</li>
                        </ul>
                    `);
                })
                
            }
        }
        new Details()
    })
})